﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Max
    /// </summary>
    public class Max : BaseImageFilter, ITwoSourceFilter
    {
        protected bool m_bReturnColor = true;
        protected internal delegate float MinMaxDelegate(float f1, float f2);
        protected internal MinMaxDelegate m_MinMaxDelegate = new MinMaxDelegate(Math.Min);
        /// <summary>
        /// Initializes a new instance of the <see cref="Max"/> class.
        /// this gets the maximum per pixel of image1 und image2. The result will be returned. 
        /// Both pics have to be of the same size
        /// This is equivalent to Math.Max in maths
        /// </summary>
        public Max()
        {
            M_PROCESSING_MODE = PROCESSING_MODE.Color;
        }

        /// <summary>
        /// Gets or sets a value indicating whether [return color].
        /// </summary>
        /// <value><c>true</c> if [return color]; otherwise, <c>false</c>.</value>
        public bool ReturnColor
        {
            get { return m_bReturnColor; }
            set { m_bReturnColor = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Max"/> class.
        /// </summary>
        /// <param name="_max">The _max.</param>
        internal Max(Max _max)
        {
            this.m_bReturnColor = _max.m_bReturnColor;
            this.m_MinMaxDelegate = _max.m_MinMaxDelegate;
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            return Process((UnsafeBitmap)_bitmap.Clone(), _bitmap);
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Max(this);
        }

        #region ITwoSourceFilter Members

        /// <summary>
        /// Processes the specified bmpimg.
        /// </summary>
        /// <param name="_bitmap1"></param>
        /// <param name="_bitmap2"></param>
        /// <returns></returns>
        public UnsafeBitmap Process(UnsafeBitmap _bitmap1, UnsafeBitmap _bitmap2)
        {
            UnsafeBitmap bitmap = (UnsafeBitmap)_bitmap1.Clone();
            ColorCalculation calculation = Definitions.ColorCalculationDictionaryProcessingMode[M_PROCESSING_MODE];
            int x = 0;
            int y = 0;
            int nHeight = _bitmap1.Width;
            int nWidth = _bitmap1.Height;
            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    Color color1 = _bitmap1.GetPixel(x, y);
                    Color color2 = _bitmap2.GetPixel(x, y);
                    float calculation1 = calculation(color1);
                    float calculation2 = calculation(color2);
                    float fMax = Math.Max(calculation1, calculation2);
                    if (m_bReturnColor)
                    {
                        bitmap.SetPixel(x, y, fMax == calculation1 ? color1 : color2);
                    }
                    else
                    {
                        bitmap.SetPixel(x, y, Color.FromArgb((int)fMax));
                    }
                }
            }
            return bitmap;
        }

        #endregion
    }
}
